
var DOMCOM;
var active_art="";
var active_law="";

function Set(L) {
  this._tab=new Array();
  if(L) {
    if(typeof(L)=="string") {
      var ll= new List(L); this._tab=ll.toTab();
    } else {
      this._tab=L._tab;// copy constructor
    }
  }
  this.add = function (e) { this._tab[e]=1; }
  this.toList = function () { var ll=new List();
			      for(var e in this._tab) ll.push(e);
                              return ll.getValue();
  }
  this.addList  = function (L) { var iter= new List_iterator(L); 
                                 while(!iter.end()) { this._tab[iter.getValue()]=1; iter.next()}
                               }
  this.is_empty = function() { return this._tab.length == 0;}
  this.is_elemin = function(e) { return this._tab[e];}

  this.union = function(s2) {
    var _set;
    var _tab1;
    if(this._tab.length < s2._tab.length){
      _tab=this._tab;
      _set=new Set(s2);
    } else {
      _tab=s2._tab;
      _set=new Set(this);
    }
    for(var e in _tab) {      
	_set.add(e);      
    }
    return _set;
  }

  this.intersect = function(s2) {
    var _set=new Set();
    var _tab1,_tab2;
    if(this._tab.length < s2._tab.length){
      _tab1=this._tab;
      _tab2=s2._tab;
    } else {
      _tab2=this._tab;
      _tab1=s2._tab;
    }
    for(var e in _tab1) {
      if(_tab2[e]) {
	_set.add(e);
      }
    }
    return _set;
  }
  this.filter = function (f) {
    var _set=new Set();
    for(var e in this._tab) {
      if(eval(f+"("+e+")")) { 	
	_set.add(e);
	//alert("filter "+f+" add "+e+"->"+_set.toList());
      }
    }
    return _set;
  }
  this.notfilter = function (f) {
    var _set=new Set();
    for(var e in this._tab) {
      if(!eval(f+"("+e+")")) {
	_set.add(e);
	//alert("notfilter "+f+" add "+e+"->"+_set.toList());
      }
    }
    return _set;
  }

  this.filter2 = function (f,b) {
    var _set=new Set();
    for(var e in this._tab) {
      //alert(f+"("+e+","+b+")");
      if(eval(f+"("+e+","+b+")")) {	
	_set.add(e);
      }
    }
    return _set;
  }
  this.tab = function () {
    return this._tab;
  }
}

function Set_iterator(S) {
  if(!S || S.is_empty()) {
    this.end = function () { return true; }
  } else {
    this._set=S._tab ;
    this._last=S._tab.length;
    this._current=-1;
    this.next= function() {
      this._current++;
      while(this._current<this._last) {
	if(this._set[this._current]==1) break;
        this._current++;
      } 
    }
    this.getValue= function() {
      return this._current;
    }
    this.end = function() {
      return this._current>=this._set.length;
    }
    this.next();
  }
} 


function loadtmpl(name) {
  var XMLDOM=new ActiveXObject("Msxml2.DOMDocument");
  XMLDOM.load(name);
  if(XMLDOM.parseError.errorCode != 0) { 
    alert("Template "+name +" not found");
    return 0;
  } 
  DOMCOM=XMLDOM.selectSingleNode('comm');
  active_law=DOMCOM.getAttribute("law");  
  return 1;
}

function IsClaimEqDep(cl) {
  var eq=GetClaimEq(cl);
  return eq && is_cldependent(eq);
}


var ACTIVE_SETS= new Array();
var ACTIVE_LEVEL=0;


function filter_set(in_set,expr,elem) {
  var or_iter= new List_iterator(expr,"+");
  var out_set= in_set;
  var or_set = new Set();
  while(!or_iter.end()) {    
    var and_iter= new List_iterator(or_iter.getValue(),".");
    var and_set=in_set;
    while(!and_iter.end()) {    
      switch(and_iter.getValue()) {
       case "inv":
	//alert("I1:"+out_set.toList());
	and_set=and_set.filter("IsClaimNovelandInventive");        
	//alert("I2:"+out_set.toList());
	break;
      case "!nov":           
	//alert("N1:"+out_set.toList());
	and_set=and_set.filter("IsClaimNotNovel");          
	//alert("N2:"+out_set.toList());
	break;
      case "!inv":
	//alert("I1:"+out_set.toList());
	and_set=and_set.filter("IsClaimNotInventive");        
	//alert("I2:"+out_set.toList());
	break;
      case "dep":
	//alert("D1:"+out_set.toList());
	and_set=and_set.filter("is_cldependent");        
	//alert("D2:"+out_set.toList());  
	break;        
      case "!dep":
	//alert("ND1:"+out_set.toList());
	and_set=and_set.filter("is_clindependent");        
	//alert("ND2:"+out_set.toList());
	break;
      case "eq":
	//alert("EQ1:"+out_set.toList());
	and_set=and_set.filter("GetClaimEq");
	//alert("EQ2:"+out_set.toList());
	break;
      case "!eq":
	//alert("NOEQ1:"+out_set.toList());
	and_set=and_set.notfilter("GetClaimEq");
	//alert("NOEQ2:"+out_set.toList());
	break;
      case "eqdep":
	//alert("EQDEP1:"+out_set.toList());
	and_set=and_set.filter("IsClaimEqDep");
	//alert("EQDEP2:"+out_set.toList());
	break;
      case "elem_eq":
	//alert("ISEQ1: in "+out_set.toList());
	and_set=and_set.filter2("IsClaimEq",elem);
	//alert("ISEQ2:"+out_set.toList());
	break;
      }            	
      //alert(expr+":"+e_iter.getValue()+"->"+out_set.toList());
      and_iter.next();
    }
    or_set=or_set.union(and_set);
    or_iter.next();
  }
  alert(in_set.toList()+" "+expr+" "+or_set.toList());  
  return or_set;
}

var DONE_SET;

function parsetmpl(level,comm,active_set,elem) {
  //alert("parsetmpl( "+level+","+comm.tagName+", "+active_set.toList()+","+(elem||"")+")");  

  ACTIVE_SETS[level]=active_set;
  ACTIVE_LEVEL=level;

  switch(comm.tagName) {
  case "comm":
    //alert("Active set is "+active_set.toList());
    var txt="";
    active_law    =comm.getAttribute("law") || "no law !";
    if(!active_set.is_empty()) {      
      for(var i=0; i< comm.childNodes.length; i++) {
	txt+=parsetmpl(level+1,comm.childNodes(i),active_set);
      }
    }
    return txt;
  case "section":
    var txt="";
    active_art    =comm.getAttribute("article") || "no article !";
    active_set=filter_set(active_set,comm.getAttribute("data"));   
    if(!active_set.is_empty()) {
      for(var i=0; i< comm.childNodes.length; i++) {
	txt+=parsetmpl(level+1,comm.childNodes(i),active_set,elem);
      }
    }
    return txt+BR;
  case "repeat":
    var txt="";
    var repeat_set    =filter_set(active_set,comm.getAttribute("data"));    
    if(!repeat_set.is_empty()) {
      //alert("repeat through "+active_set.toList());
      var s_iter= new Set_iterator(repeat_set);       
      while(!s_iter.end()) {
	for(var i=0; i< comm.childNodes.length; i++) {
	  //alert("repeat "+comm.childNodes(i).tagName+" on "+s_iter.getValue());
	  txt+=parsetmpl(level+1,comm.childNodes(i),active_set,s_iter.getValue());
	}                 
	s_iter.next();
      }
      //alert("end repeat");      
    }	    
    return txt;
    
  case "elem_header":
    return eval(active_law+"_"+active_art+"_elem_header("+elem+")")+BR;
  case "elem_body":
    DONE_SET.add(elem);
    return eval(active_law+"_"+active_art+"_elem_body("+elem+")")+BR;  

  case "list_body":     
  case "list_mutatis":
    DONE_SET=DONE_SET.union(active_set);
  case "list_header":        
    var expr=comm.getAttribute("data");
    if(expr && !active_set.is_empty()) {
      active_set    =filter_set(active_set,expr,elem);
    }
    if(!active_set.is_empty()) {
      //alert(active_law+"_"+active_art+"_"+comm.tagName+"(active_set)");
      return eval(active_law+"_"+active_art+"_"+comm.tagName+"(active_set)")+BR;      
    } 
    return "";
  }
 
  alert("unknown tag "+comm.tagName);
  return "ERROR: Unknown tag "+comm.tagName;
}

function check_all_done(allcl) {
  var cl_iter = new List_iterator(allcl);
  var missing = new List();
  while(!cl_iter.end()) {
    if(!DONE_SET.is_elemin(cl_iter.getValue())) {
      missing.push(cl_iter.getValue());
    }
    cl_iter.next();
  }
  alert("Claims "+missing.getValue()+" not covered");
}

function tst_tmpl() {
  if(loadtmpl("tmpl/pct.xml")) {
    DONE_SET=new Set();
    var clms=filteredclaims();
    var txt=parsetmpl(0,DOMCOM,new Set(clms));
    check_all_done(clms);
    return txt;
  }
  return("Cannot open file ");
}



